<?php

class VS_Update
{
	private $_srcPath;
	
	private $_destPath;
	
	private $_ignoreList;
	
	private $_logFile;
	
	function __construct($config)
	{
		if(!isset($config['srcPath']) 
				|| !isset($config['destPath']) 
				|| !isset($config['ignoreList']) 
				|| !isset($config['logFile'])) {
			throw new Exception("Class 'Update': Invalid Config.");
		}
		
		$this->_srcPath = $config['srcPath'];
		
		$this->_destPath = $config['destPath'];
		
		$this->_ignoreList = $config['ignoreList'];
		
		$this->_logFile = $config['logFile'];
	}
	
	function run()
	{
		$this->_updateDir();
		$this->_removeDeletedFiles();
	}
	
	private function _removeDeletedFiles($dir='')
	{
		// Read Target Path for missing files
		$dh = @opendir($this->_destPath.$dir);
		while(false !== ($file = readdir($dh))) {
			if(in_array( $file, $this->_ignoreList) || preg_match('/\.bkp$/i', $file))
				continue;
			
			if(!file_exists($this->_srcPath.$dir.'/'.$file)) {
				rename($this->_destPath.$dir.'/'.$file, $this->_destPath.$dir.'/'.$file.'.BKP');
				file_put_contents($this->_logFile, 'D '.$dir.'/'.$file."\n", FILE_APPEND);
			}
			else if(is_dir($this->_destPath.$dir.'/'.$file)) {
				$this->_removeDeletedFiles($dir.'/'.$file);
			}
		}
	}
	
	private function _updateDir($dir='')
	{
		$dh = @opendir($this->_srcPath.$dir);
		while(false !== ($file = readdir($dh))) {
			if(in_array($file, $this->_ignoreList))
				continue;
	
			if(is_dir($this->_srcPath.$dir.'/'.$file)) {
				if(!file_exists($this->_destPath.$dir.'/'.$file) || !is_dir($this->_destPath.$dir.'/'.$file)) {
				    
					$this->_xcopy($this->_srcPath.$dir.'/'.$file, $this->_destPath.$dir.'/'.$file);
					file_put_contents($this->_logFile, 'A '.$file."\n", FILE_APPEND);
				}
				else {
				    
					$this->_updateDir($dir.'/'.$file);
				}
			} else {
				$this->_updateFile($dir.'/'.$file);
			}
		}
		closedir($dh);
	}
	
	private function _updateFile($file)
	{
		if(file_exists($this->_destPath.$file)) {
			if(strcmp(file_get_contents($this->_destPath.$file), file_get_contents($this->_srcPath.$file))) {
				rename($this->_destPath.$file, $this->_destPath.$file.'BKP');
				copy($this->_srcPath.$file, $this->_destPath.$file);
				file_put_contents($this->_logFile, 'M '.$file."\n", FILE_APPEND);
			}
		}
		else {
			copy($this->_srcPath.$file, $this->_destPath.$file);
			file_put_contents($this->_logFile, 'A '.$file."\n", FILE_APPEND);
		}
	}
	
	private function _xcopy($src, $dest)
	{
	    $dh = @opendir($src);
	    while(false !== ($file = readdir($dh))) {
			if (($file == '.') || ($file == '..') || !is_readable($src.'/'.$file))
				continue;
	
			if (is_dir($src.'/'.$file)) {
				mkdir($dest . '/' . $file);
				$this->_xcopy($src.'/'.$file, $dest.'/'.$file);
			} else {
				copy($src.'/'.$file, $dest.'/'.$file);
			}
		}
		closedir($dh);
	}
}